#include "struct_imatge.h"
#include "im_ppm.h"

/******************************************************************************************************/

void MatarImatge(imatge i){

	free(i->data);
	free(i);

}

imatge CrearImatge(int c,int h,int w){

	imatge i;

	i=(imatge)malloc(sizeof(im));

	i->data=(t_data*)calloc(c*h*w,sizeof(t_data));
	i->h=h;
	i->w=w;
	i->c=c;

	return i;

}

imatge CrearImatge(imatge ima){

	imatge i;

i=CrearImatge(ima->c,ima->h,ima->w);

	return i;

}

imatge CrearImatge(int c,imatge ima)
{
	imatge i;

i=CrearImatge(c,ima->h,ima->w);

	return i;

}



imatge LlegirImatgePPM(char* nom,int *err){

	FILE *c;
	int c1,c2,c3,error=0;
	long i,j,k;
	char s1[MAX_CAR],s2[MAX_CAR],s3[MAX_CAR];
	unsigned short *ss;
	unsigned char  *sc;
	long pos,h,w,n,depth;
	imatge ima;

	ima=NULL;
	if((c=fopen(nom,"rb"))==NULL){
		error=-1;
	}else{
	  
		c1=fgetc(c);
		c2=fgetc(c);
		c3=fgetc(c);

		pos=3;

		if(c1=='P' && c3=='\n'){
   		
			/******* evitar els comentaris ***********/

			c1=fgetc(c);
			pos++;

			while(c1=='#'){
				
				c3=fgetc(c);
				pos++;

				while(c3!='\n'){
					
					c3=fgetc(c);
					pos++;

				}
	
				c1=fgetc(c);
				pos++;

			}

			fseek(c,pos-1,SEEK_SET);

			/****************llegir les mides de la imatge************/

			fscanf(c,"%s %s\n",s1,s2);
   			w=atol(s1);
			h=atol(s2);

  			fscanf(c,"%s",s3);	
			c1=fgetc(c);
			depth=atol(s3);

			while(c1!='\n'){
				fscanf(c,"%s",s3);	
				c1=fgetc(c);
			}
					  
			/**************nombre de bandes***********/

			if(c2=='6' || c2=='3'){
				n=3;
			}else if(c2=='2' || c2=='5'){
				n=1;
			}else{
				error=-4;
			}

			/****************************************/

			if(error==0) ima=CrearImatge(n,h,w); if(ima->data==NULL) error=-99;

			if(c2=='6' || c2=='5'){	 //raw

				if(depth==255){

					if(sizeof(unsigned char)!=sizeof(t_data))
					{

						sc=(unsigned char*)calloc(n*h*w,sizeof(unsigned char));
						fread(sc,sizeof(unsigned char),n*h*w,c);

						for(i=0;i<(n*h*w);i++){
							ima->data[i]=((t_data) (sc[i]));
						}

						free(sc);

					}else{

						fread(ima->data,sizeof(unsigned char),n*h*w,c);

					}

					error=0;


				}else if(depth==65535){
				 			
					if(sizeof(unsigned short)!=sizeof(t_data)){

						ss=(unsigned short*)calloc(n*h*w,sizeof(unsigned short));
						fread(ss,sizeof(unsigned short),n*h*w,c);

						for(i=0;i<(n*h*w);i++){
							ima->data[i]=((t_data) (ss[i]/256));
						}

						free(ss);

					}else{

						fread(ima->data,sizeof(unsigned short),n*h*w,c);

					}

					error=0;

				}else{
					
					error=-5;

				}
 				   
			}else if(c2=='2' || c2=='3'){	   //ascii
				
				for(i=0;i<h;i++){
					for(j=0;j<w;j++){
						for(k=0;k<n;k++){

							fscanf(c,"%s ",s1);
							ima->data[k+j*n+w*n*i]=(t_data) atoi(s1);

						}
					}
				}

				error=0;

			}else{

				error=-2;

			}

		}else{
			error=-3;
		}
			   
		fclose(c);
	   
	}
	*err=error;
	return ima;

}

imatge CopiarImatge(imatge ima)
{
	long int i; imatge im2; long int numpixels;
	im2=CrearImatge(ima);
	numpixels=(long int)(ima->h)*(long int)(ima->w)*(long int)(ima->c);
	for(i=0;i<numpixels;i++)
	{
		(im2->data[i])=(ima->data[i]);
	}
return im2;
}


void CopiarImatgeExistent(imatge ima,imatge im2)
{
	long int i; long int numpixels;
	numpixels=(long int)(ima->h)*(long int)(ima->w)*(long int)(ima->c);
	for(i=0;i<numpixels;i++)
	{
		(im2->data[i])=(ima->data[i]);
	}
}


void AfegirImatge(imatge ima,imatge ima2,unsigned char offset)
{
	long int i; long int numpixels;
	numpixels=(long int)(ima->h)*(long int)(ima->w)*(long int)(ima->c);
	for(i=0;i<numpixels;i++)
	{
		if((ima2->data[i])==0) if((ima->data[i])!=0) 
		(ima2->data[i])=(ima->data[i])+offset;
	}
}


void EscriureImatgePPM(imatge ima,char* nom,int *err){

	FILE *c;
	char ch,*s;
	long h,w,n,i;

	*err=0;

	if((c=fopen(nom,"wb"))==NULL){
		*err=-1;
	}else{
	  
		if(ima!=NULL){

			h=ima->h;
			w=ima->w;
			n=ima->c;

			if(n==3){

				ch='6';

			}else if(n==1){

				ch='5';

			}else{

				*err=-1;

			}
			
			if(*err==0){

				s=(char*)calloc(n*h*w,sizeof(char));

				sprintf(s,"P%c\n%ld %ld\n255\n",ch,w,h);
				fwrite(s,sizeof(unsigned char),strlen(s),c);
				
				if(sizeof(unsigned char)!=sizeof(t_data)){

					for(i=0;i<(n*h*w);i++){
						s[i]=((unsigned char) (ima->data[i]));
					}

					fwrite(s,sizeof(unsigned char),n*h*w,c);

				}else{

					fwrite(ima->data,sizeof(unsigned char),n*h*w,c);

				}

				free(s);

			}
		
		}
		
		fclose(c);

	}
		
} 

int pR(int i,int j, int w)
{
	return 3*(i*w+j);

}

int pG(int i,int j, int w)
{
	return 3*(i*w+j)+1;

}

int pB(int i,int j, int w)
{
	return 3*(i*w+j)+2;
}